home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_46 / sbfm.c < prev    next >
C/C++ Source or Header  |  1995-01-01  |  4KB  |  150 lines

  1. #include <stdio.h>
  2. #include <dos.h>
  3. #include "sb.h"
  4.  
  5. static void WriteFM(int chip, int addr, unsigned char data)
  6. {
  7.     register int ChipAddr = SbIOaddr + ((chip) ? RIGHT_FM_ADDRESS :
  8.                         LEFT_FM_ADDRESS);
  9.  
  10.     outportb(ChipAddr,addr);
  11.     inportb(ChipAddr);
  12.  
  13.     outportb(ChipAddr+1,data);
  14.     inportb(ChipAddr);
  15.     inportb(ChipAddr);
  16.     inportb(ChipAddr);
  17.     inportb(ChipAddr);
  18. }
  19.  
  20. void Sb_FM_Reset(void)
  21. {
  22.     WriteFM(0,1,0);
  23.     WriteFM(1,1,0);
  24. }
  25.  
  26. void Sb_FM_Key_Off(int voice)
  27. {
  28.     unsigned char reg_num;
  29.     int chip = voice / 11;
  30.     
  31.     /* turn voice off */
  32.     reg_num = 0xB0 + voice % 11;
  33.  
  34.     WriteFM(chip,reg_num,0);
  35. }
  36.  
  37. void Sb_FM_Key_On(int voice, int freq, int octave)
  38. {
  39.     register unsigned char reg_num;
  40.     unsigned char tmp;
  41.     int chip = voice / 11;
  42.  
  43.     reg_num = 0xa0 + voice % 11;
  44.  
  45.     WriteFM(chip,reg_num,freq & 0xff);
  46.  
  47.     reg_num = 0xb0 + voice % 11;
  48.     tmp = (freq >> 8) | (octave << 2) | 0x20;
  49.  
  50.     WriteFM(chip,reg_num,tmp);
  51. }
  52.  
  53. void Sb_FM_Voice_Volume(int voice, int vol)
  54. {
  55.     unsigned char reg_num;
  56.     int chip = voice / 11;
  57.  
  58.     reg_num = 0x40 + voice % 11;
  59.  
  60.     WriteFM(chip,reg_num,vol);
  61. }
  62.  
  63. void Sb_FM_Set_Voice(int voice_num, FM_Instrument *ins)
  64. {
  65.     register unsigned char op_cell_num;
  66.     int cell_offset;
  67.     int chip = voice_num / 11;
  68.  
  69.     voice_num %= 11;
  70.  
  71.     /* check on voice_num range */
  72.     cell_offset = voice_num % 3 + ((voice_num / 3) << 3);
  73.  
  74.     /* set sound characteristic */
  75.     op_cell_num = 0x20 + (char)cell_offset;
  76.  
  77.     WriteFM(chip,op_cell_num,ins->SoundCharacteristic[0]);
  78.     op_cell_num += 3;
  79.     WriteFM(chip,op_cell_num,ins->SoundCharacteristic[1]);
  80.  
  81.     /* set level/output */
  82.     op_cell_num = 0x40 + (char)cell_offset;
  83.     WriteFM(chip,op_cell_num,ins->Level[0]);
  84.     op_cell_num += 3;
  85.     WriteFM(chip,op_cell_num,ins->Level[1]);
  86.  
  87.     /* set Attack/Decay */
  88.     op_cell_num = 0x60 + (char)cell_offset;
  89.     WriteFM(chip,op_cell_num,ins->AttackDecay[0]);
  90.     op_cell_num += 3;
  91.     WriteFM(chip,op_cell_num,ins->AttackDecay[1]);
  92.  
  93.     /* set Sustain/Release */
  94.     op_cell_num = 0x80 + (char)cell_offset;
  95.     WriteFM(chip,op_cell_num,ins->SustainRelease[0]);
  96.     op_cell_num += 3;
  97.     WriteFM(chip,op_cell_num, ins->SustainRelease[1]);
  98.  
  99.     /* set Wave Select */
  100.     op_cell_num = 0xE0 + (char)cell_offset;
  101.     WriteFM(chip,op_cell_num,ins->WaveSelect[0]);
  102.     op_cell_num += 3;
  103.     WriteFM(chip,op_cell_num,ins->WaveSelect[1]);
  104.  
  105.     /* set Feedback/Selectivity */
  106.     op_cell_num = (unsigned char)0xC0 + (unsigned char)voice_num;
  107.     WriteFM(chip,op_cell_num,ins->Feedback);
  108. }
  109.  
  110. #ifdef TEST
  111. void main()
  112. {
  113.     static FM_Instrument instrument = {
  114.         0x11, 0x01, 0x8a, 0x40,
  115.         0xf1, 0xf1, 0x11, 0xb3,
  116.         0x00, 0x00, 0x06, 0x00,
  117.         0x00, 0x00, 0x00, 0x00 
  118.     };
  119.     int notes[12] = {0x16B,0x181,0x198,0x1B0,0x1CA,0x1E5,
  120.              0x202,0x220,0x241,0x263,0x287,0x2AE};
  121.  
  122.     if(GetSBParams(&SbIOaddr,&SbIRQ,&SbDMAchan))
  123.     {
  124.         puts("BLASTER environment variable not set.");
  125.         exit(1);
  126.     }
  127.  
  128.     Sb_FM_Reset();
  129.  
  130.     Sb_FM_Set_Voice(0,&instrument);
  131.     Sb_FM_Set_Voice(1,&instrument);
  132.     Sb_FM_Set_Voice(11,&instrument);
  133.     Sb_FM_Set_Voice(12,&instrument);
  134.  
  135.     Sb_FM_Key_On(0,notes[11],2);
  136.     Sb_FM_Key_On(1,notes[3],3);
  137.     Sb_FM_Key_On(11,notes[6],3);
  138.     Sb_FM_Key_On(12,notes[11],3);
  139.  
  140.     getch();
  141.  
  142.     Sb_FM_Key_Off(0);
  143.     Sb_FM_Key_Off(1);
  144.     Sb_FM_Key_Off(11);
  145.     Sb_FM_Key_Off(12);
  146.  
  147.     Sb_FM_Reset();
  148. }
  149. #endif
  150.